10 فصل دهم - تفکر پایتونی

فصل ۱۰

لیست ها

در این فصل یکی از پرکاربردترین ساختار داده ای پایتون که به صورت پیش فرض در آن قرار داده شده است را بررسی می کنیم. شما در این فصل بیشتر با شی گرایی و اشیا آشنا خواهید شد و خواهید دید که وقتی بیش از یک نام برای یک شی داریم، چه اتفاقی می افتد.

بخش اول : یک لیست یک دنباله است

مانند یک رشته، یک لیست دنباله ای از مقادیر است. از مقادیر در یک لیست به عنوان عناصر یا گاهی موارد یک لیست یاد میشود.

راه های متفاوتی برای ساخت یک لیست وجود دارد. ساده ترین راه آن، تعریف عناصر یک لیست در یک براکت ( [ و ] ) است.

[10, 20, 30, 40]

['crunchy frog', 'ram bladder', 'lark vomit']

مثال اول یک لیست از چهار عدد صحیح می باشد و دومی یک لیست از سه رشته است. لازم نیست که عناصر یک لیست همه از یک نوع باشند. لیست زیر شامل یک رشته، یک عدد اعشاری، یک عدد صحیح و ( :) ) یک لیست دیگر است :

[‘spam’, 2.0, 5, [10, 20]]

تعریف یک لیست در داخل یک لیست دیگر به عنوان لیست تو در تو شناخته میشود.

یک لیست که هیچ عنصری نداشته باشد، لیست خالی نامیده میشود. شما میتوانید یک لیست خالی را با استفاده از براکت های خالی بسازید، [].

همانطوری که انتظار دارید، شما میتوانید مقادیر یک لیست را به متغیرها اختصاص دهید :

>>> cheeses = ['Cheddar', 'Edam', 'Gouda']\ >>> numbers = [42, 123]\ >>> empty = []\ >>> print(cheeses, numbers, empty)\ ['Cheddar', 'Edam', 'Gouda'] [42, 123] []

شکل ۱۰ - ۱

بخش ۲ : لیست ها تغییر پذیر هستند

نحوه دسترسی به عناصر یک لیست همانند دسترسی به کاراکترهای یک رشته است -- عملگرا براکت. عبارت داخل براکت ها مشخص کننده شاخص عنصر مورد نظر را معین میکند. با یاد داشته باشید که شاخص یک لیست از صفر شروع میشود.

>>> cheeses[0]\ 'Cheddar'

برخلاف رشته ها، لیست ها قابل تغییر هستند. زمانی که عملگر براکت در سمت چپ یک تساوی قرار میگرد، مشخص کننده عنصر اختصاص داده شده از لیست است.

>>> numbers = [42, 123]\ >>> numbers[1] = 5\ >>> numbers\ [42, 5]

در مثال بالا، عنصر شماره خانه یک که ۱۲۳ بود الان ۵ میباشد.

شکل ۱۰ -۱ نمودار حالت را برای سه لیست cheeses، numbers، empty نشان میدهد :

لیست ها با جعبه هایی که لغت "list" بالای آنها و خارج از عناصر لیست ( که در داخل جعبه نوشته شده اند)، مشخص هستند. cheese،به لیستی با سه عنصر که در شاخص های 0، 1 و ۲ قرار دارند، اشاره میکند. numbers، شامل دو عنصر است که همانطوری که نمودار نشان میدهد، عنصر دوم از ۵ به ۱۲۳ مجدد اختصاص داده شده است. empty به یک لیست بدون عنصر اشاره میکنم.

شاخص های لیست همانند شاخص های رشته عمل میکنند:

  • هر عبارت عدد صحیحی میتواند به عنوان یک شاخص باشد
  • اگر بخواهید عنصری را بخوانید یا بنوسید که وجود ندارد با پیغام IndexError برخورد میکنید
  • اگر شاخص یک مقدار منفی باشد، به صورت وارونه از انتهای لیست میشمارد.

عملگر in روی لیستها نیز کار میکند:

>>> cheeses = ['Cheddar', 'Edam', 'Gouda']\ >>> 'Edam' in cheeses\ True\ >>> 'Brie' in cheeses

False

بخش ۳ : پیمایش یک لیست

رایجترین روش برای پیمایش عناصر یک لیست استفاده از حلقه for است. نحوه استفاده از حلقه for همانند استفاده آن در رشته ها است :

for cheese in cheeses:\ print(cheese)

این روش برای خواندن عناصر یک لیست کاربرد دارد اما اگر می خواهید عناصر را تغییر دهید، به شاخص آنها نیاز دارید. یک روش معمول استفاده از ترکیب توابع درون سازی شده range و len :

for i in range(len(numbers)):\ numbers[i] = numbers[i] * 2

حلقه بالا، لیست را پیمایش کرده و تمام عناصر آنرا به روز مینماید. تابع len تعداد عناصر لیست را برمیگرداند. تابع range یک لیست از شاخص های ۰ تا n-1 ( که n طول لیست است ) را بازمیگرداند. با هر بار چرخش در حلقه متغیر i شاخص عنصر بعدی را میگیرد. جمله تساوی در بدنه حلقه از متغیر i استفاده میکند تا مقدار قدیمی عنصر را خوانده و مقدار جدید را به آن اختصاص دهد.

یک حلقه for روی یک لیست خالی هیچ موقع بدنه حلقه را اجرا نمیکند.

for x in []:

print('This never happens.')

اگرچه یک لیست میتواند شامل لیست دیگری باشد، لیست تو در تو همچنان به عنوان یک عنصر شمرده میشود. به عنوان مثال طول لیست زیر ۴ است :

['spam', 1, ['Brie', 'Roquefort', 'Pol le Veq'], [1, 2, 3]]

بخش ۴ : عمگرهای یک لیست :

عملگر + ، لیست ها را با هم ادغام میکند.

>>> a = [1, 2, 3]\ >>> b = [4, 5, 6]\ >>> c = a + b\ >>> c

[1, 2, 3, 4, 5, 6]

عملگر * ، لیست را به تعداد دفعات داده شده، تکرار میکند.

>>> [0] * 4\ [0, 0, 0, 0]\ >>> [1, 2, 3] * 3\ [1, 2, 3, 1, 2, 3, 1, 2, 3]

مثال اول، [0] را ۴ بار تکرار میکند. مثال دوم لیست [1, 2, 3] را ۳ بار تکرار میکند.

بخش ۵ : بریدن لیست

عملگر برش ( : ) روی لیست ها هم کار میکند.

>>> t = ['a', 'b', 'c', 'd', 'e', 'f']\ >>> t[1:3]\ ['b', 'c']\ >>> t[:4]

['a', 'b', 'c', 'd']\ >>> t[3:]\ ['d', 'e', 'f']

اگر شما شاخص اول را حذف کنید، برش از ابتدای لیست شروع میشود، اگر شما شاخص دوم را حذف کنید، برش تا انتهای لیست ادامه پیدا میکند و اگر شما هر دو شاخص را حذف کنید، برش، یک نسخه از تمام لیست خواهد بود.

>>> t[:]\ ['a', 'b', 'c', 'd', 'e', 'f']

از آنجایی که لیست ها قابل تغییر هستند، سودمند است که یک نسخه از لیست قبل از انجام اعمالی که لیست را تغییر میدهند، تهیه کنیم.

عملگر برش، در سمت چپ یک تساوی، میتواند چندین عنصر را به روز نماید.

>>> t = ['a', 'b', 'c', 'd', 'e', 'f']\ >>> t[1:3] = ['x', 'y']\ >>> t\ ['a', 'x', 'y', 'd', 'e', 'f']

بخش ۶ : توابع لیست

پایتون توابعی را برای عملیات متفاوت روی لیست ها تهیه کرده است. به طور مثال، append یک عنصر به انتهای لیست اضافه میکند.

>>> t = ['a', 'b', 'c']

>>> t.append('d')

>>> t

['a', 'b', 'c', 'd']

extend یک لیست به عنوان پارامتر گرفته و تمام عناصر آن را به انتهای لیست مورد نظر اضافه میکند.

>>> t1 = ['a', 'b', 'c']

>>> t2 = ['d', 'e']

>>> t1.extend(t2)

>>> t1

['a', 'b', 'c', 'd', 'e']

در مثال بالا، لیست t2 تغییری نمیکند.

sort عناصر یک لیست را از کم به زیاد ( پایین به بالا ) مرتب میکند

>>> t = ['d', 'c', 'e', 'b', 'a']

>>> t.sort()

>>> t

['a', 'b', 'c', 'd', 'e']

بسیاری از توابع لیست خروجی نداشته، آنها لیست را تغییر میدهند و None را به عنوان خروجی بازمیگردانند. اگر به صورت اتفاقی شما عبارت t = t.sort() را بنویسید، از نتیجه نهایی ناامید خواهید شد.

بخش ۷ : نگاشت، فیلتر و کاستن

برای اینکه تمام اعداد در یک لیست را با هم جمع کنید میتوانید از یه حلقه مانند زیر استفاده کنید :

def add_all(t):

total = 0

for x in t:

total += x

return total

در ابتدا متغیر total با 0 مقداردهی شده. هر باری که حلقه اجرا میشود متغیر x بک عنصراز لیست را میگیرد. عملگر += یک راه کوتاه برای به روزرسانی متغیر را فراهم کرده است. عبارت تساوی زیر

total += x

برابر است با :

total = total + x

با اجرا شدن حلقه، متغیر total مجموع عناصر را در خود نگه میدارد. متغیری بدین روش استفاده میشود گاهی با عنوان انباشتگر خطاب میشود.

حساب کردن مجموع عناصر یک لیست یک عملیات معمول است که پایتون یک تابع درون ساز شده برای آن تهیه کرده است، sum:

>>> t = [1, 2, 3]

>>> sum(t)

6

یک عملیات که در آن مجموعه ای از عناصر در یک مقدار ترکیب میشوند، گاهی به عنوان عملیات کاستن نام برده میشود.

گاهی شما میخواهید یک لیست را پیمایش کنید تا یک لیست دیگر ایجاد کنید. به عنوان مثال، تابع زیر یک لیست از رشته ها گرفته و یک لیست جدید که شامل رشته ها با حروف بزرگ است را برمیگرداند :

def capitalize_all(t):

res = []

for s in t:

res.append(s.capitalize())

return res

در مثال بالا، res با یک لیست خالی مقدار دهی اولیه شده است. هر بار که حلقه اجرا میشود، ما عنصر بعدی را به لیست اضافه میکنیم. بنابراین res یک نمونه دیگر از انباشتگر میباشد.

یک عملیات مانند capitalize_all گاهی با عنوان عملیات نگاشت خطاب میشود، چرا که در این عملیات یک نگاشت برای هر یک از عناصر یک لیست رخ میدهد.

یکی دیگر از عملیات معمول روی لیست ها، انتخاب چند عنصر از یک لیست و بازگرداندن آنها به عنوان یک لیست جدید میباشد. به عنوان مثال، تابع زیر یک لیست از رشته ها گرفته و یک لیست را که تنها شامل رشته هایی با حروف بزرگ است بازمیگرداند.

def only_upper(t):

res = []

for s in t:

if s.isupper():

res.append(s)

return res

isupper یک تابع برای رشته است که اگر رشته تنها شامل حروف بزرگ باشد، True بازمیگرداند.

یک عملیات مانند only_upper به عنوان یک فیلتر شناخته میشود. چرا که بعضی از عناصرلیست را انتخاب میکند و آنها را از بقیه عناصر جدا میکند.

بسیاری از عملیات و توابع پرکاربرد در لیست را میتوان با ترکیبی از نگاشت، فیلتر و کاستن، بیان کرد.

بخش ۸ : پاک کردن عناصر یک لیست

راه های زیادی برای پاک کردن یک عناصر یک لیست وجود دارد. اگر شما شاخص یک عنصر را در یک لیست بدانید، میتوانید از pop استفاده کنید :

>>> t = ['a', 'b', 'c']

>>> x = t.pop(1)

>>> t

['a', 'c']

>>> x

'b'

pop ، لیست را تغییر میدهد و عنصر پاک شده را به عنوان خروجی بازمیگرداند. اگر شما شاخص را به عنوان پارامتر ورودی ندهید، این تابع آخرین عنصر لیست را پاک کرده و آن را به عنوان خروجی باز میگرداند.

اگر شما عنصر پاک شده را در خروجی نمیخواهید، میتوانید از عملگر del استفاده کنید :

>>> t = ['a', 'b', 'c']

>>> del t[1]

>>> t

['a', 'c']

اگر شما مقدار عنصر مورد نظر را میدانید و شاخص آن را نمیدانید، میتوانید از remove استفاده کنید :

>>> t = ['a', 'b', 'c']

>>> t.remove('b')

>>> t

['a', 'c']

مقدار بازگردانده شده توسط remove، None است.

برای پاک کردن بیش از یک عنصر، میتوانید از del و شاخص بریدن (:) استفاده کنید :

>>> t = ['a', 'b', 'c', 'd', 'e', 'f']

>>> del t[1:5]

>>> t

['a', 'f']

به صورت معمول، با استفاده از شاخص بریدن تمامی عنصرها از شاخص اول تا شاخص دوم انتخب میشوند ( به جز عنصر اشاره شده در شاخص دوم )

بخش ۹ : لیست ها و رشته ها

یک رشته ترتیبی از کاراکترها بود و یک لیست ترتیبی از مقادیر است، اما یک لیست از کاراکترها همانند یک رشته نیست. برای تبدیل یک رشته به یک لیستی از کاراکترها، میتوانید از list استفاده کنید :

>>> s = 'spam'\ >>> t = list(s)\ >>> t\ ['s', 'p', 'a', 'm']\

شکل ۱۰.۲

چون list اسم یک تابع درون ساز شده است، لذا بهتر است از آن به عنوان اسم یک متغیر استفاده نکنید. من همچنین از l استفاده نمیکنم چون بسیار شبیه 1 است. به همین خاطر من از t استفاده میکنم.

تابع list یک رشته را به حرف های جداگانه تقسیم میکند. اگر میخواهید یک رشته را به چند کلمه تقسیم کنید، میتوانید از split استفاده کنید :

>>> s = 'pining for the fjords'\ >>> t = s.split()\ >>> t\ ['pining', 'for', 'the', 'fjords']\

یک پارامتر اختیاری به عنوان جداکننده، مشخص میکند که چه پارامتری نشان دهنده مرزهای کلمات است. در مثال زیر، یک دش به عنوان جداکننده استفاده شده است :

>>> s = 'spam-spam-spam'\ >>> delimiter = '-'\ >>> t = s.split(delimiter)\ >>> t

['spam', 'spam', 'spam']

join برعکس split عمل میکند. یک لیستی از رشته ها را گرفته و تمام عناصر آن را به هم میچسباند. join یک تابع رشته است و به همین دلیل شما باید آن را روی جداکننده مورد نظر خود استفاده کنید و لیست را به عنوان پارامتر به آن پاس کنید:

>>> t = ['pining', 'for', 'the', 'fjords']\ >>> delimiter = ' '\ >>> s = delimiter.join(t)\ >>> s

'pining for the fjords'

در مثال بالا، جداکننده کاراکتر فاصله است و join بین کلمات یک فاصله میگذارد. برای چسباندن رشته ها بدون فاصله کافی است میتوانید از رشته خالی ''، به عنوان جداکننده استفاده کنید.

بخش ۱۰ : اشیا و مقادیر

اگر تساوی های زیر را اجرا کنیم :

a = 'banana'\ b = 'banana'\

ما میدانیم که a و b هر دو به یک رشته اشاره میکنند، اما نمیدانیم که به یک رشته یکسان اشاره میکنند یا نه. دو حالت ممکن در شکل ۱۰.۲ نشان داده شده است.

در یک حالت، a و b هر دو به شی متفاوت که مقدار یکسانی دارند اشاره میکنند. در حالت دوم، هر دو به یک شی اشاره میکنند.

برای چک کردن اینکه این دو متغیر به یک شی اشاره میکنند، میتوانید از عملگر is استفاده کنید:

شکل ۱۰.۳

شکل ۰.۴

>>> a = 'banana'\ >>> b = 'banana'\ >>> a is b\ True

در مثال بالا، پایتون فقط یک شی رشته ایجاد کرده و هر دو متغیر a و b یه آن اشاره میکنند. ولی وقتی دو لیست ایجاد میکنند میتوانید دو شی متفاوت را داشته باشید :

>>> a = [1, 2, 3]\ >>> b = [1, 2, 3]\ >>> a is b\ False\

بنابراین دیاگرام حالت آن شبیه به شکل ۱۰.۳ میشود.

در این حالت میگوییم که دو لیست معادل هستند چون عناصر برابری دارند ولی عناصر آنها یکسان نیستند. اگر دو شی یکسان باشند، آنها معادل هم هستند. اما اگر معدل باشند، لزوما یکسان نیستند.

تا الان، ما از شی و مقدار به جای یک دیگر استفاده میکردیم. اما دقیق تر است تا بگوییم که یک شی حاوی مقداری است. اگر شما [1,2,3] را ارزیابی کنید شما یک شی از لیست دریافت میکنید که مقادیر آن ترتیبی از اعداد صحیح هستند. اگر لیست دیگری عناصر یکسانی داشته باشد، میگوییم که مقادیر آنها یکسان است، اما دو شی متفاوت هستند.

بخش ۱۱ : نام مستعار

اگر متغیر a به شیی اشاره کند و شما تساوی b = a را اجرا کنید، سپس هر دو متغیر به یک شی اشاره خواهند کرد :

>>> a = [1, 2, 3]\ >>> b = a\ >>> b is a\ True\

دیاگرام حالت این مثال به صورت شکل ۱۰.۴ میباشد.

اختصاص یک متغیر به یک شی را یک ارجاع می نامند. در مثال بالا دو ارجاع به یک شی وجود دارد.

یک شی با یسش از یک ارجاع، بیش از یک اسم دارد، به همین دلیل میگوییم که شی، نام مستعار دارد.

اگر شی تغییر پذیر باشد، تغییراتی که با یک اسم مستعار در آن ایجاد میشود، سایر اسامی را هم تحت تاثیر قرار میدهد.

شکل ۱۰.۵

>>> b[0] = 42\ >>> a\ [42, 2, 3]\

اگرچه این رفتار، میتواند مقدی باشد ولی احتمال خطا را بیشتر میکند. به صورت عمومی، امنتر است که از اسم های مستعار ببرای اشیای تغییر پذیر استفاده نکنیم.

برای اشیا تغییر ناپذیر، همانند رشته ها، استفاده از اسم مستعار مشکلات زیادی را ایجاد نمیکند. در این مثال :

a = 'banana'\ b = 'banana'\

هیچ فرقی نمیکند که a و b به دو شی متفاوت اشاره میکنند یا یکسان

بخش ۱۲ ؛ پارامترهای لیست

زمانی که یک لیست را به عنوان پارامتر به یک تابع ارسال میکنید. تابع یک ارجاع به لیست را در اختیار خواهد داشت. اگر تابع، لیست را تغییر دهد، لیست اصلی نیز تغییر پیدا میکند. برای مثال delete_head اولین عنصر یک لیست را حذف میکند.

def delete_head(t):\ del t[0]

که به صورت زیر استفاده میشود.

>>> letters = ['a', 'b', 'c']\ >>> delete_head(letters)\ >>> letters\ ['b', 'c']\

متغیر t و letters به صورت مستعاری برای یک شی استفاده شده اند. نمودار پشته در شکل ۱۰.۵ نشان داده شده است.

یه متنی اینجا هست که نمیدونم چی ترجمه کنم

این امر که فرق بین عملگرهایی که لیست را تغییر میدهند و یا یک لیست جدید ایجاد میکنند را بدانیم، مهم است. برای مثال، عملگر append یک لیست را تغییر میدهد اما عملگر + یک لیست جدید ایجاد میکند :

>>> t1 = [1, 2]\ >>> t2 = t1.append(3)\ >>> t1\ [1, 2, 3]\ >>> t2\ None\

عملگر append لیست را تغییر میدهد و None را باز میگرداند.

>>> t3 = t1 + [4]\ >>> t1\ [1, 2, 3]\ >>> t3\ [1, 2, 3, 4]\ >>> t1\

عملگر + یک لیست جدید ایجاد میکند و لیست را اصلی را بدون تغییر باقی میگذارد.

تفاوت میان این دو مهم است زمانی که میخواهید توابعی بنوسید که قرار است لیست ها را تغییر دهند.

برای مثال، تابع زیر عنصر اول لیست را حذف نمیکند :

def bad_delete_head(t):

t = t[1:] # WRONG!

عملگر برش، یک لیست جدید ایجاد میکند که در نتیجه عمل تساوی، متغیر t به لیست جدید اشاره میکند که لیست مرجع را تغییر نمیدهد.

>>> t4 = [1, 2, 3]\ >>> bad_delete_head(t4)\ >>> t4\ [1, 2, 3]\

در ابتدای bad_delete_head، متغیر t و t4 به یک لیست اشاره میکند. در انتها، متغیر t به یک لیست جدید اشاره میکند اما t4 هنوز به لیست اصلی اشاره کرده که تغییر نکرده است.

یک راه دیگر ایت است که یک تابع بنویسیم تا لیست جدید را ایجاد کرده و آن را باز میگرداند. به عنوان مثال، tail تمام عنصر را به جز عنصر ابتدای لیست بازمیگرداند.

def tail(t):\ return t[1:]\

این تابع، لیست اصلی را بدون تغییر باقی میگذارد و به صورت زیر استفاده میشود :

>>> letters = ['a', 'b', 'c']\ >>> rest = tail(letters)\ >>> rest\ ['b', 'c']\

بخش ۱۳ - اشکال زدایی

استفاده بدون دقت از لیست ها ( و سایر اشیای قابل تغییر ) میتواند باعث ساعت های اشکال زدایی شود. در اینجا یک سری از دام های رایج را نشان داده و راه هایی برای جلوگیری از آن را بیان میکنیم.

  1. بسیار از توابع لیست، پارامتر ورودی را تغییر داده و None باز میگرداند. این برعکس توابع رشته است که یک رشته جدید باز میگردانند و رشته اصلی را بدون تغییر باقی میگذارند.

اگر عادت به نوشتن کدهای رشته مانند زیر دارید :

word = word.strip()

ممکن است که کدهایی مانند کد زیر را برای لیست ها بنویسید که اشتباه است :

t = t.sort() # WRONG!\

چون sort به عنوان مقدار خروجی None را بازمیگرداند، عملیات بعدی که با متغیر t انجام میدهید به احتمال زیاد اشتباه خواهد شد.

قبل از استفاده ای توابع و عملگر های لیست، بهتر است که مستندات مربوطه را با دقت بخوانید و سپس آنها را در محیط تعاملی امتحان کنید.

  1. یک اصطلاح یا نشانه انتخاب کنید و به آن بچسبید !

قسمتی از مشکل کار کردن با لیست ها این است که راه های زیادی برای انجام کارها وجود دارد، به عنوان مثال، برای حذف یک عنصر از لیست میتوانید از pop یا remove یا del و یا حتی عملگر برش استفاده کنید.

برای اضافه کردن یک عنصر، شما میتوانید از تابع append یا عملگر + استفاده کنید. با فرض اینکه t یک لیست و x یک عنصر از لیست است. موارد زیر درست هستند :

t.append(x)\ t = t + [x]\ t += [x]\

و موارد زیر اشتباه هستند :

t.append([x])# WRONG !

t = t.append(x)# WRONG !

t + [x]# WRONG !

t = t + x# WRONG !

هر کدام از این موارد در محیط تعاملی پایتون امتحان کنید تا مطمین شوید که از عملکرد آنها اطلاع دارید. به این نکته توچه کنید که تنها مورد آخر خطای زمان اجرا را برمیگرداند. سایر موارد قانونی هستند ولی کار اشتباهی را انجام میدهند.

  1. نسخه ها متعدد درست کنید و از اسم های مستعار استفاده نکنید.

اگر میخواهید از تابعی مانند sort که عناصر را تغییر میدهد، استفاد کنید اما از طرفی میخواهید که لیست اصلی را هم نگه دارید، میتوانید یک کپی از آن بگیرید :

>>> t = [3, 1, 2]\ >>> t2 = t[:]\ >>> t2.sort()\ >>> t\ [3, 1, 2]\ >>> t2\ [1, 2, 3]\

در این مثال، شما میتوانید از تابع، درون ساز شده sorted هم استفاده کنید که یک لیست مرتب شده جدید را باز گردانده و لیست اصلی را بدون تغییر باقی میگذارد:

>>> t2 = sorted(t)\ >>> t\ [3, 1, 2]\ >>> t2\

[1, 2, 3]

بخش ۱۴ : واژه نامه

لیست : یک ترتیبی از مقادیر است

عنصر : یک مقدار در یک لیست ( یا ترتیب ) است که گاهی با عنوان «مورد» هم خطاب میشود

لیست تودرتو : یک لیست که به عنوان عنصری در لیست دیگر باشد

ذخیره کننده : متغیری که داخل یک حلقه برای ذخیره سازی مقادیر استفاده میشود.

انتساب افزوده : دستوری که مقدار یک متغیر را با استفاده از عملگر += به روز می نماید

کاهش : الگوی پردازه ای که ترتیبی از مقادیر را پیمایش کرده و عناصر را در یک متغیر ذخیره میکند

نگاشت : الگوی پردازه ای که ترتیبی از مقادیر را پیمایش کرده و یک عمل خاص را روی همه آنها انجام میدهد

فیلتر : الگوی پردازه ای که یک لیست را پیمایش کرده و عناصر خاصی را جدا میکند

شی : چیزی که متغیر میتواند به آن اشاره کن. هر شی دارای مقدار و نوع میباشد.

معادل :‌ دارای مقادیر یکسان

یکسان : یک شی بودن

مرجع : ارتباط بین یک متغیر و مقدار آن

استعاره : شرایطی که دو یا چند متغیر به یک شی اشاره میکنند

تقسیم کننده : یک کاراکتر یا رشته برای مشخص کردن اینکه یک رشته از کجا باید تقسیم شود

تمرینات:

۱۰.۱۵ تمرین‌ها

می‌توانید راه‌حل‌های این تمرین‌ها را از http://thinkpython2.com/code/list_exercises.py دانلود کنید.

تمرین ۱۰.۱: تابعی به نام nested_sum بنویسید که لیستی از لیست‌های اعداد صحیح را دریافت کرده و تمام زیر‌لیست‌ها را با هم مانند مثال زیر جمع کند.

>>> t = [[1, 2], [3], [4,5,6]]

>>> nested_sum(t)

21

نمرین ۱۰.۲: تابعی به نام cumsum بنویسید که لیستی از اعداد بگیرد و مجموع تجمعی آنها را بازگرداند که لیستی است که هر

>>> t = [1, 2, 3]

>>> cumsum(t)

[1, 3, 6]

تمرین ۱۰.۳: تابعی به نام middle بنویسید که یک لیست بگیرد و لیست جدیدی بازگرداند که شامل همه اعضا جز عضو اول و عضو آخر. مانند زیر:

>>> t = [1, 2, 3, 4]

>>> middle(t)

[2, 3]

تمرین ۱۰.۴: تابعی به نام chop بنویسید که یک لیست بگیرد و با برداشتن عضو اول و آخر آن لیست را تغییر دهد، و باز گرداند.

>>> t = [1, 2, 3, 4]

>>> chop (t)

>>> t

[2, 3]

تمرین ۱۰.۵: تابعی به نام is_sorted که لیستی به عنوان پارامتر بگیرد و اگر لیست به صورت نزولی مرتب بود True و در غیر این صورت False برگرداند.

>>> is_sorted([1, 2, 2])

True

>>> is_sorted([‘b’, ‘a’])

False

\ تمرین ۱۰.۶: دو کلمه آناگرام هستند اگر بتوانید با حروف یکی، دیگری را بنویسیم. تابعی به نام is_anagram بنویسید که دو رشته را دریافت کرده، و اگر anagram هستند True بازگرداند.

تمرین ۱۰.۷: تابعی به نام has_duplicates بنویسید که یک لیست به عنوان ورودی دریافت کند و اگر لیست دارای عضوی بود که بیش از یک بار تکرار شده بود، True برگرداند. (نباید لیست اصلی را تغییر دهد)

تمرین ۱۰.۸: این تمرین متعلق به مساله پارادوکس روز تولد است که می‌توانید درباره آن http://en.wikipedia.org/wiki/Birthday_paradox را مطالعه کنید.

اگر ۲۳ دانش‌آموزدر کلاس شما وجود داشته باشند، شانس این که دو نفر تاریخ تولد یکسان داشته باشند چقدر است؟ شما می‌توانید این احتمال را با ساختن نمونه‌های تصادفی ۲۳ تاریخ تولد و گشتن یه دنبال تاریخ‌های یکسان محاسبه کنید. راهنمایی: می‌توانید با استفاده از تابع randint در ماژول random تاریخ تولد تصادفی تولید کنید.

می‌توانید راه حل من را از http://thinkpython2.com/code/birthday.py دانلود کنید.

تمرین ۱۰.۹: تابعی بنویسید که فابل words.txt را بخواند و یک لیست با یک عضو به ازای هر کلمه بسازد. دو نسخه از این تابع بنویسید؛ یکی با استفاده از append و دیگری با استفاده از شکل t = t + [x].

کدام یک به زمان بیشتری برای اجرا نیاز دارند؟ چرا؟

راه حل: http://greenteapress.com/thinkpython2/code/wordlist.py

تمرین ۱۰.۱۰: برای بررسی وجود یک کلمه در لیستی از کلمه‌ها، شما می‌توانید از عملگر in استفاده کنید، اما کند خواهد بود زیرا این عملگر کلمات را به ترتیب جست و جو می‌کند.

چون کلمه‌ها دارای ترتیب الفبایی هستند، می‌توانیم با جست و جوی دو بخشی سرعت را افزایش دهیم که شبیه کاری است که وقتی در دیکشنری به دنبال کلمه‌ای می‌گردیم انجام می‌دهیم.

شما از وسط داده شروع می‌کنید تا ببینید کلمه‌ای که به دنبال آن می‌گردید آیا قبل از کلمه‌ای که در میانه لیست آمده وجود دارد؟ اگر پاسخ مثبت است، شما نیمه اول لیست را با روش مشابه جست و جو می‌کنید؛ در غیر این صورت نیمه دوم را جست و جو می‌کنید.

در هر صورت شما فضای جست و جوی باقی مانده را نصف می‌کنید. اگر لیست کلمه‌ها دارای ۱۱۳۸۰۹ کلمه باشد، حدود ۱۷ مرحله نیاز است تا کلمه را پیدا کنیم یا اطمینان پیدا کنیم که کلمه در آن لیست وجود ندارد.

تابعی به نام in_bisect بنویسید که یه لیست مرتب شده و کلمه هدف را به عنوان ورودی دریافت کند و در صورت وجود، اندیس کلمه هدف و در غیر این صورت None بازگرداند. یا می‌توانید مستندات ماژول bisect را مطالعه کنید و از آن استفاده کنید.

راه حل: http://thinkpython2.com/code/reverse_pair.py

تمرین ۱۰.۱۱: دو کلمه جفت معکوس هستند اگر هر کدام معکوس دیگری باشند. برنامه‌ای بنویسید که تمام جفت‌های معکوس را در لیستی از کلمات پیدا کند.

راه حل: http://greenteapress.com/thinkpython2/code/reverse_pair.py

تمرین ۱۰.۱۲: دو کلمه در هم بافته شده هستند اگر با استفاده متناوب از حروف آنها بتوان کلمه جدیدی ساخت. برای مثال، "shoe" و "cold" در هم بافته شده هستند در کلمه "schooled".

راه حل: http://greenteapress.com/thinkpython2/code/interlock.py

اعتبار: این تمرین از مثالی در http://puzzlers.org/ الهام گرفته شده است.

۱. برنامه‌ای بنویسید که تمام جفت‌های در هم بافته را بیابد. راهنمایی: تمام جفت‌ها را نشمارید!

۲. آیا می‌توانید کلمه‌ای پیدا کنید که سه‌جهته در هم بافته است؟ (هر سه کلمه‌ای که یک کلمه جدید بسازند) با شروع از اولی، دومی یا سومی؟